package com.idea.relax.tool.wechat.config;

import com.idea.relax.tool.wechat.toolkit.WechatPayHelper;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.util.PemUtil;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * @author: 沉香
 * @date: 2023/2/27
 * @description:
 */
@Order(Integer.MIN_VALUE)
@Configuration(
        proxyBeanMethods = false
)
@ConditionalOnNotEmpty(values = {
        WechatPayProperties.PREFIX + ".mch-id",
        WechatPayProperties.PREFIX + ".mch-serial-no",
        WechatPayProperties.PREFIX + ".v3-secret"
})
@EnableConfigurationProperties(WechatPayProperties.class)
public class WechatPayAutoConfiguration {

    @Bean
    public Config config(WechatPayProperties properties) {
        //去除JCE加密限制，只限于Java1.8
        erasureJCE();
        RSAAutoCertificateConfig.Builder builder = new RSAAutoCertificateConfig.Builder()
                .merchantId(properties.getMchId());
        //商户私钥
        if (!StringUtils.isEmpty(properties.getPrivateKey())) {
            builder.privateKey(PemUtil.loadPrivateKeyFromString(properties.getPrivateKey()));
        } else {
            builder.privateKey(PemUtil.loadPrivateKeyFromPath(properties.getPrivateKeyPath()));
        }
        //商户号
        return builder.merchantSerialNumber(properties.getMchSerialNo())
                .apiV3Key(properties.getV3Secret())
                .build();
    }

    private static void erasureJCE() {
        Field field;
        try {
            field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");
            field.setAccessible(true);
            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
            field.set(null, false);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Bean
    public JsapiServiceExtension jsapiService(Config config) {
        return new JsapiServiceExtension.Builder().config(config).build();
    }


    @Bean
    public WechatPayHelper wechatPayHelper(WechatPayProperties properties, JsapiServiceExtension jsapiService) {
        return new WechatPayHelper(properties, jsapiService);
    }


}
